package symbols;

public class Morpheme {

    private final Codes code;
    private final Position start;
    private final Position end;
    private final String text;
    private final int number;

    public Morpheme(final Codes code, final Position start, final Position end, final String text, final int number) {
        this.code = code;
        this.start = start;
        this.end = end;
        this.text = text;
        this.number = number;
    }

    public Morpheme(final Codes code, final Position start, final Position end) {
        this(code, start, end, "", 0);
    }

    public Morpheme(final Codes code, final Position start, final Position end, final String text) {
        this(code, start, end, text, 0);
    }

    public Morpheme(final Codes code, final Position start, final Position end, final int number) {
        this(code, start, end, "", number);
    }

    public Codes getCode() {
        return this.code;
    }

    public Position getStart() {
        return this.start;
    }

    public Position getEnd() {
        return this.end;
    }

    public Position getPosition() {
        return getStart();
    }

    public String getText() {
        return this.text;
    }

    public int getNumber() {
        return this.number;
    }

    public String toString() {
        final StringBuilder builder = new StringBuilder();
        builder.append("<").append(getCode().toString());
        if (getCode().equals(Codes.ident)) {
            builder.append(", ").append("\"").append(this.getText()).append("\"");
        }
        if (getCode().equals(Codes.number)) {
            builder.append(", ").append(this.getNumber());
        }
        builder.append(">\n");
        return builder.toString();
    }

    public enum Codes {
        type,
        error {
            public String toString() {
                return "unknown symbol";
            }
        },
        whileSmt {
            public String toString() {
                return "while";
            }
        },
        begin,
        trueStmt {
            public String toString() {
                return "true";
            }
        },
        bool {
            public String toString() {
                return "boolean";
            }
        },
        read,
        doneStmt {
            public String toString() {
                return "done";
            }
        },
        then,
        integer,
        print,
        fi,
        equal {
            public String toString() {
                return "=";
            }
        },
        doStmt {
            public String toString() {
                return "do";
            }
        },
        ifStmt {
            public String toString() {
                return "if";
            }
        },
        semi {
            public String toString() {
                return ";";
            }
        },
        mult {
            public String toString() {
                return "*";
            }
        },
        falseStmt {
            public String toString() {
                return "false";
            }
        },
        elseStmt {
            public String toString() {
                return "else";
            }
        },
        score {
            public String toString() {
                return "-";
            }
        },
        plus {
            public String toString() {
                return "+";
            }
        },
        assign {
            public String toString() {
                return ":=";
            }
        },
        openBracket {
            public String toString() {
                return "(";
            }
        },
        closeBracket {
            public String toString() {
                return ")";
            }
        },
        end,
        ident,
        number,
        eof,
        program,
        comma {
            public String toString() {
                return ",";
            }
        },
        slash {
            public String toString() {
                return "/";
            }
        },
        stmt {
            public String toString() {
                return "statement";
            }
        }, op {
            public String toString() {
                return "operator";
            }
        }, lessThan {
            public String toString() {
                return ">";
            }
        }
    }
}
